package com.examination.client.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.examination.client.config.WechatPayProperties;
import com.examination.client.domian.dto.PushOrderDTO;
import com.examination.client.domian.dto.PushOrderVO;
import com.examination.client.entity.BuyMessageRecord;
import com.examination.client.entity.SiteMessage;
import com.examination.client.enums.OrderStatusEnum;
import com.examination.client.service.IBuyMessageRecordService;
import com.examination.client.service.ISiteMessageService;
import com.examination.client.service.PayService;
import com.examination.client.util.JsonUtils;
import com.examination.client.util.UserInfoUtil;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.enums.TradeType;
import com.ijpay.core.kit.HttpKit;
import com.ijpay.core.kit.IpKit;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.model.UnifiedOrderModel;
import com.jfinal.kit.StrKit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Service
public class PayServiceImpl implements PayService {
    @Resource
    IBuyMessageRecordService buyMessageRecordService;

    @Resource
    private WechatPayProperties wechatPayProperties;
    @Resource
    ISiteMessageService siteMessageService;

    @Override
    public PushOrderVO pushOrder(PushOrderDTO pushOrderDTO, HttpServletRequest request) {

        String ip = IpKit.getRealIp(request);
        if (StrKit.isBlank(ip)) {
            ip = "127.0.0.1";
        }

        String out_trade_no = WxPayKit.generateStr();
        Map<String, String> params = UnifiedOrderModel
                .builder()
                .appid(wechatPayProperties.getAppId())
                .mch_id(wechatPayProperties.getMchId())
                .nonce_str(WxPayKit.generateStr())
                .out_trade_no(out_trade_no)
                .body("订单支付")
                .total_fee(pushOrderDTO.getTotalFee().toString())
                .spbill_create_ip(ip)
                .notify_url(wechatPayProperties.getDomain()+wechatPayProperties.getNotifyUrl())
                .trade_type(TradeType.APP.getTradeType())
                .attach(UserInfoUtil.getSiteId().toString())
                .build()
                .createSign(wechatPayProperties.getPartnerKey(), SignType.HMACSHA256);

        String xmlResult = WxPayApi.pushOrder(false, params);

        log.info(xmlResult);
        Map<String, String> result = WxPayKit.xmlToMap(xmlResult);

        String returnCode = result.get("return_code");
        String returnMsg = result.get("return_msg");
        if (!WxPayKit.codeIsOk(returnCode)) {
           throw new RuntimeException(returnMsg);
        }
        String resultCode = result.get("result_code");
        if (!WxPayKit.codeIsOk(resultCode)) {
            throw new RuntimeException(returnMsg);
        }
        String prepayId = result.get("prepay_id");

        Map<String, String> packageParams = WxPayKit.appPrepayIdCreateSign(wechatPayProperties.getAppId(), wechatPayProperties.getMchId(), prepayId,
                wechatPayProperties.getPartnerKey(), SignType.HMACSHA256);

        String json = JsonUtils.toJson(packageParams);
        PushOrderVO pushOrderVO = JSON.parseObject(json, PushOrderVO.class);
        log.info("返回apk的参数:" + pushOrderVO);

        //保存下单信息
        BuyMessageRecord buyMessageRecord = new BuyMessageRecord();
        buyMessageRecord.setMessageNum(pushOrderDTO.getMessageNum());
        buyMessageRecord.setCreateTime(new Date());
        buyMessageRecord.setOrderNo(out_trade_no);
        buyMessageRecord.setOrderAmount(pushOrderDTO.getTotalFee());
        buyMessageRecord.setOrderStatus(OrderStatusEnum.NO_PAY.getCode());
        buyMessageRecord.setSiteId(Integer.valueOf(UserInfoUtil.getSiteId()));
        buyMessageRecord.setUpdateTime(new Date());
        buyMessageRecord.setOperatorId(UserInfoUtil.getUserid());
        buyMessageRecordService.save(buyMessageRecord);
        return pushOrderVO;
    }

    @Override
    public String callback(HttpServletRequest request) {
        try {
            String result = HttpKit.readData(request);
            log.info("微信回调参数：{}", result);
            Map<String, String> map = WxPayKit.xmlToMap(result);
            log.info("微信回调参数：{}", result);
            boolean verify = WxPayKit.verifyNotify(map, wechatPayProperties.getPartnerKey(),SignType.HMACSHA256);
            Map<String, String> returnMap = new HashMap<>();
            if (verify) {
                returnMap.put("return_code", "SUCCESS");
                returnMap.put("return_msg", "OK");
                //更新订单
                String out_trade_no = map.get("out_trade_no");
                LambdaQueryWrapper<BuyMessageRecord> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(BuyMessageRecord::getOrderNo,out_trade_no);
                BuyMessageRecord buyMessageRecord = buyMessageRecordService.getOne(queryWrapper);
                if(Objects.isNull(buyMessageRecord)){
                    return "FAIL";
                }
                if(OrderStatusEnum.ALREADY_PAY.getCode().equals(buyMessageRecord.getOrderStatus())){
                    String xml = WxPayKit.toXml(returnMap);
                    log.info("微信回调结果：{}", xml);
                    return xml;
                }
                buyMessageRecord.setOrderStatus(OrderStatusEnum.ALREADY_PAY.getCode());
                buyMessageRecord.setUpdateTime(new Date());
                buyMessageRecordService.updateById(buyMessageRecord);

                //记录短信数量(总.可用.已使用)
                LambdaQueryWrapper<SiteMessage> siteMessageQueryWrapper = new LambdaQueryWrapper<>();
                siteMessageQueryWrapper.eq(SiteMessage::getSiteId,buyMessageRecord.getSiteId());
                SiteMessage siteMessage = siteMessageService.getOne(siteMessageQueryWrapper);
                if(Objects.isNull(siteMessage)){
                    siteMessage = new SiteMessage();
                    siteMessage.setSiteId(buyMessageRecord.getSiteId());
                    siteMessage.setTotalBuyNum(buyMessageRecord.getMessageNum());
                    siteMessage.setMessageNum(buyMessageRecord.getMessageNum());
                    siteMessage.setCreateTime(new Date());
                    siteMessageService.save(siteMessage);
                    log.info("保存短信统计信息：{}", JsonUtils.toJson(siteMessage));
                }else {
                    int totalBuyNum = siteMessage.getTotalBuyNum() + buyMessageRecord.getMessageNum();
                    siteMessage.setTotalBuyNum(totalBuyNum);
                    siteMessage.setMessageNum(totalBuyNum-siteMessage.getAlreadyUseNum());
                    siteMessage.setUpdateTime(new Date());
                    siteMessageService.updateById(siteMessage);
                    log.info("更新短信统计信息：{}", JsonUtils.toJson(siteMessage));
                }
            } else {
                returnMap.put("result_code", "FAIL");
            }
            String xml = WxPayKit.toXml(returnMap);
            log.info("微信回调结果：{}", xml);
            return xml;
        } catch (Exception e) {
            log.info("微信回调失败：{}:",e);
        }
        return null;
    }


}
